﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using DllInjector;

namespace ApplicationDllManager
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();

            dlgProcessList.OnProcessSelect += new frmProcessList.OnProcessSelectDelegate(dlgProcessList_OnProcessSelect);
        }

        frmProcessList dlgProcessList = new frmProcessList();
        Process SelectedProcess = null;

        void RefreshModulesList()
        {
            try
            {
                dataGridProcessModules.Rows.Clear();

                SelectedProcess.Refresh();
                foreach (ProcessModule module in SelectedProcess.Modules)
                {
                    dataGridProcessModules.Rows.Add(
                        module.BaseAddress.ToString("X"),
                        module.ModuleMemorySize.ToString("X"),
                        module.EntryPointAddress.ToString("X"),
                        module.ModuleName,
                        module.FileVersionInfo.FileVersion,
                        module.FileName
                    );
                }

                toolStripLastPerformedAction.Text = String.Format("Re/Loaded \"{0}\"", SelectedProcess.ProcessName);
                lblModulesCount.Text = String.Format("Modules Count: {0}", SelectedProcess.Modules.Count);
            }
            catch (Exception ex)
            {
                toolStripLastPerformedAction.Text = ex.Message;
                lblModulesCount.Text = "Modules Count: 0";
            }
        }

        private void btnRefreshModulesView_Click(object sender, EventArgs e)
        {
            RefreshModulesList();
        }

        void dlgProcessList_OnProcessSelect(OnProcessSelectEventArgs e)
        {
            SelectedProcess = Process.GetProcessesByName(e.ProcessName)[0];
            RefreshModulesList();
        }

        private void btnSelectProcess_Click(object sender, EventArgs e)
        {
            dlgProcessList.ShowDialog();
        }

        private void btnInjectModuleToProcess_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog()
            {
                Filter = "*.dll files|*.dll"
            };

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                if (SelectedProcess != null && !SelectedProcess.HasExited)
                {
                    bool injected = Injector.InjectDll(SelectedProcess, openFileDialog.FileName);
                    if (injected)
                    {
                        toolStripLastPerformedAction.Text =
                            String.Format("Module \"{0}\" injected in process \"{1}\"", openFileDialog.SafeFileName, SelectedProcess.ProcessName);
                    }
                    else
                    {
                        toolStripLastPerformedAction.Text = "Injection failed !";
                    }
                }
                else
                {
                    toolStripLastPerformedAction.Text = "Process not found or not responding.";
                }
            }
        }

        private void btnEjectSelectedModule_Click(object sender, EventArgs e)
        {
            if (dataGridProcessModules.Rows.Count > 0)
            {
                string moduleName = dataGridProcessModules.SelectedRows[0].Cells[3].Value.ToString();
                uint moduleAddress = Convert.ToUInt32(dataGridProcessModules.SelectedRows[0].Cells[0].Value.ToString(), 16);
                try
                {
                    bool ejected = Injector.EjectDll(SelectedProcess, moduleAddress);
                    if (ejected)
                    {
                        toolStripLastPerformedAction.Text = String.Format("Module \"{0}\" ejected from process \"{1}\"", moduleName, SelectedProcess.ProcessName);
                    }
                    else
                    {
                        toolStripLastPerformedAction.Text = "Module ejection failed !";
                    }
                }
                catch (Exception ex)
                {
                    toolStripLastPerformedAction.Text = ex.Message;
                }
            }
        }
    }
}
